package com.powernode.dispatch.client;

import com.alibaba.fastjson.JSONObject;
import com.powernode.common.execption.PowerException;
import com.powernode.common.result.ResultCodeEnum;
import com.powernode.dispatch.config.XxlJobClientConfig;
import com.powernode.model.entity.dispatch.XxlJobInfo;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

/**
 * 给xxl job动态的添加任务，启动任务，删除任务等操作
 */
@Slf4j
@Component
public class XxlJobClient {

    @Resource
    private XxlJobClientConfig xxlJobClientConfig;

    @Resource
    private RestTemplate restTemplate;

    /**
     * 添加任务
     * @param executorHandler  @xxljob注解中的内容
     * @param param  传入的参数
     * @param cron   cron表达式
     * @param desc   任务描述
     * @return
     */
    public Long addJob(String executorHandler, String param,String cron,String desc) {
        //表单对象
        XxlJobInfo xxlJobInfo = new XxlJobInfo();

        //构建表单对象
        xxlJobInfo.setJobGroup(xxlJobClientConfig.getJobGroupId());

        xxlJobInfo.setJobDesc(desc);//任务描述
        xxlJobInfo.setAuthor("pat"); //负责人
        xxlJobInfo.setScheduleType("CRON");//调度类型
        xxlJobInfo.setScheduleConf(cron);//cron表达式
        xxlJobInfo.setGlueType("BEAN");
        xxlJobInfo.setExecutorHandler(executorHandler);//job handler

        xxlJobInfo.setExecutorRouteStrategy("FIRST");
        xxlJobInfo.setExecutorBlockStrategy("SERIAL_EXECUTION");
        xxlJobInfo.setMisfireStrategy("FIRE_ONCE_NOW");
        xxlJobInfo.setExecutorTimeout(0);
        xxlJobInfo.setExecutorFailRetryCount(0);

        //点击添加按钮，将xxljobInfo发送到添加地址上
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.add("Content-Type", "application/json");
        HttpEntity<XxlJobInfo> entity = new HttpEntity<>(xxlJobInfo, httpHeaders);

        //添加任务的地址
        String addUrl = xxlJobClientConfig.getAddUrl();

        //发送请求
        ResponseEntity<JSONObject> response = restTemplate.postForEntity(addUrl, entity, JSONObject.class);

        if (response.getStatusCode().value() == 200 && response.getBody().getInteger("code") == 200){
            //添加成功
            return response.getBody().getLong("content");
        }

        throw new PowerException(ResultCodeEnum.XXL_JOB_ERROR);
    }


    /**
     * 启动任务
     */
    public Boolean startJob(Long jobId){
        XxlJobInfo xxlJobInfo = new XxlJobInfo();
        xxlJobInfo.setId(jobId.intValue());

        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.add("Content-Type", "application/json");
        HttpEntity<XxlJobInfo> entity = new HttpEntity<>(xxlJobInfo, httpHeaders);

        //获取启动任务的地址
        String startUrl = xxlJobClientConfig.getStartJobUrl();

        ResponseEntity<JSONObject> response = restTemplate.postForEntity(startUrl, entity, JSONObject.class);

        if (response.getStatusCode().value() == 200 && response.getBody().getInteger("code") == 200){
            //启动成功
            return true;
        }

        throw new PowerException(ResultCodeEnum.XXL_JOB_ERROR);
    }


    /**
     * 停止任务
     * @param jobId
     * @return
     */
    public Boolean stopJob(Long jobId) {
        XxlJobInfo xxlJobInfo = new XxlJobInfo();
        xxlJobInfo.setId(jobId.intValue());

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<XxlJobInfo> request = new HttpEntity<>(xxlJobInfo, headers);

        //停止的url地址
        String url = xxlJobClientConfig.getStopJobUrl();
        ResponseEntity<JSONObject> response = restTemplate.postForEntity(url, request, JSONObject.class);
        if(response.getStatusCode().value() == 200 && response.getBody().getIntValue("code") == 200) {
            log.info("停止xxl执行任务成功:{},返回信息:{}", jobId, response.getBody().toJSONString());
            return true;
        }
        log.info("停止xxl执行任务失败:{},返回信息:{}", jobId, response.getBody().toJSONString());
        throw new PowerException(ResultCodeEnum.XXL_JOB_ERROR);
    }

    public Boolean removeJob(Long jobId) {
        XxlJobInfo xxlJobInfo = new XxlJobInfo();
        xxlJobInfo.setId(jobId.intValue());

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<XxlJobInfo> request = new HttpEntity<>(xxlJobInfo, headers);

        String url = xxlJobClientConfig.getRemoveUrl();
        ResponseEntity<JSONObject> response = restTemplate.postForEntity(url, request, JSONObject.class);
        if(response.getStatusCode().value() == 200 && response.getBody().getIntValue("code") == 200) {
            log.info("删除xxl执行任务成功:{},返回信息:{}", jobId, response.getBody().toJSONString());
            return true;
        }
        log.info("删除xxl执行任务失败:{},返回信息:{}", jobId, response.getBody().toJSONString());
        throw new PowerException(ResultCodeEnum.XXL_JOB_ERROR);
    }


    /**
     * 添加并启动
     * @param executorHandler
     * @param param
     * @param corn
     * @param desc
     * @return
     */
    public Long addAndStart(String executorHandler, String param, String corn, String desc) {
        XxlJobInfo xxlJobInfo = new XxlJobInfo();
        xxlJobInfo.setJobGroup(xxlJobClientConfig.getJobGroupId());
        xxlJobInfo.setJobDesc(desc);
        xxlJobInfo.setAuthor("pat");
        xxlJobInfo.setScheduleType("CRON");
        xxlJobInfo.setScheduleConf(corn);
        xxlJobInfo.setGlueType("BEAN");
        xxlJobInfo.setExecutorHandler(executorHandler);
        xxlJobInfo.setExecutorParam(param);
        xxlJobInfo.setExecutorRouteStrategy("FIRST");
        xxlJobInfo.setExecutorBlockStrategy("SERIAL_EXECUTION");
        xxlJobInfo.setMisfireStrategy("FIRE_ONCE_NOW");
        xxlJobInfo.setExecutorTimeout(0);
        xxlJobInfo.setExecutorFailRetryCount(0);

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<XxlJobInfo> request = new HttpEntity<>(xxlJobInfo, headers);

        String url = xxlJobClientConfig.getAddAndStartUrl();
        ResponseEntity<JSONObject> response = restTemplate.postForEntity(url, request, JSONObject.class);
        if(response.getStatusCode().value() == 200 && response.getBody().getIntValue("code") == 200) {
            log.info("增加并开始执行xxl任务成功,返回信息:{}", response.getBody().toJSONString());
            //content为任务id
            return response.getBody().getLong("content");
        }
        log.info("增加并开始执行xxl任务失败:{}", response.getBody().toJSONString());
        throw new PowerException(ResultCodeEnum.XXL_JOB_ERROR);
    }

}
